<?php


require_once(dirname(__FILE__).'/../../common/log.php');
require_once(dirname(__FILE__).'/../../common/defines.php');
require_once(dirname(__FILE__).'/../../common/return.php');
require_once(dirname(__FILE__).'/../../database/mysql.class.php');
require_once(dirname(__FILE__).'/../../database/redis.class.php');

require_once(dirname(__FILE__).'/common.php');


$body  = file_get_contents('php://input');   
logd("recv: ".$body);

$data  = json_decode($body, true);
if ((!isset($data['userId'])) || (!isset($data['kefuId'])) || (!isset($data['type'])) || (!isset($data['data'])))
{
    loge("params error: ".$body);

    failure(ERR_PARAM);
}

$kefuId  = $data['kefuId'];
$userId  = $data['userId'];
$umid    = make_umid($kefuId, $userId);
$lock    = "server:kefuLock:$kefuId";

$redis   = new RedisUtils();
$redis->select(7);

do
{
    $ret  = $redis->hget("server:current", $userId);
    if (empty($ret))
    {
        $ret  = $redis->hsetnx("server:current", $userId, $kefuId);
    }
    else
    {
        if ($ret != $kefuId)
        {
            failure(10, '已分配其他客服');
        }
    }
} while (empty($ret));

//连接数据库
$mysql  = new mysqldb();
$ret    = $mysql->open_db(['dbname' => 'love-hole']);
if ($ret === FAILURE)
{
    failure(ERR_SYSTEM);
}

//检查当前客服是否在线（因为有可能刚发送消息，该客服就离线了）
//尝试获取当前客服的互斥锁。这里必须先对当前客服加锁（加锁成功与否都无法唯一判断当前客服是否在线，所以不对加锁结果进行判断）
//获取失败表示：1、当前客服正处于离线中（因为客服离线的时候会加锁）；2、正在为当前客服分配另一个用户的消息
//获取成功表示：1、当前客服在线；2、当前客服刚离线完成，刚释放离线锁
$redis->try_lock($lock);
//通过获取客服分数判断当前客服是否在线
//获取失败：当前客服已离线
//获取成功：当前客服在线
$ret  = $redis->zscore("server:online", $kefuId);
if (!empty($ret))
{
    //获取当前用户未被其他客服回复的消息，重新发送给当前客服
    $num  = recv_other_message($mysql, $userId, $kefuId);
    //增加当前客服分数
    $redis->zincrby("server:online", 1 + $ret, $kefuId);
}
else
{
    //获取当前用户尚未被其他客服回复的消息
    $msgs  = $mysql->select('kefu_message_info', '*', "(senderId = $userId) AND (recverId != $kefuId) AND (status = 0)");
    $num   = count($msgs);  
}

//当前用户未被其他客服回复的消息为0，则说明当前客服发送给当前用户的消息是对该用户之前发送的消息的回复，需要将该用户之前的消息标记为已回复
//当前用户未被其他客服回复的消息非0，则说明当前客服发送给当前用户的消息不是对该用户之前发送的消息的回复（比如主动联系用户时），所以不更新该用户之前消息的状态，这样如果当前客服在回复当前用户之前离线，该用户之前的消息仍然是未回复状态，还能再次被其他客服回复
if ($num === 0)
{
    //更新当前用户之前的消息为已回复
    $mysql->update('kefu_message_info', ['status' => 1], "(senderId = $userId) AND (recverId = $kefuId) AND (status = 0)");
    //将当前客服回复的消息存入数据库（标记为回复消息）
    save_message($mysql, $kefuId, $userId, $data['type'], json_encode($data['data'], JSON_UNESCAPED_UNICODE), 1, $umid);
}
else
{
    //将当前客服回复的消息存入数据库（标记为非回复消息）
    save_message($mysql, $kefuId, $userId, $data['type'], json_encode($data['data'], JSON_UNESCAPED_UNICODE), 0, $umid);
}

//对当前客服解锁
$ret  = $redis->unlock($lock);
if ($ret === FAILURE)
{
    loge("unlock $lock failed !");
}

//发送当前消息给用户
send_kmsg_message(USERID_SERVER, [(int)$userId], $data['type'], 0, $data['data'], 1, $umid);

success();
